#include "ServiceProvider.h"
#include "GameControls.h"
#include "MenuManager.h"
#include "PrintUtilities.h"
#include "StlStringAndStreams.h"
#include "Global.h"

//menus
#include "SaveMenu.h"
#include "LoadMenu.h"
#include "StartingMenu.h"
#include "TeamSelectionMenu.h"
#include "MainMenu.h"
#include "TeamsManagementMenu.h"
#include "ClassificationMenu.h"
#include "TurnsMenu.h"
#include "TeamsStatsMenu.h"
#include "LeagueStatsMenu.h"
#include "LeagueMenu.h"
#include "LeagueSelectionMenu.h"
#include "PlayTurnsMenu.h"
#include "EndLeagueMenu.h"
#include "GameOverMenu.h"
#include "PlayersStatsMenu.h"
#include "PlayersStatsShowMenu.h"
#include "PlayerMenu.h"
#include "TeamMenu.h"
#include "TeamMatchesMenu.h"
#include "MatchMenu.h"
#include "SearchMenu.h"
#include "UserSelectionMenu.h"
#include "OfferTeamMenu.h"
#include "OfferPlayerMenu.h"
#include "ShortListNotificationMenu.h"
#include "ShortListMenu.h"

#include "LeagueHistoryMenu.h"
#include "TeamHistoryMenu.h"

#include "ConfirmPanel.h"
#include "NotificationPanel.h"

#include <cassert>

MenuManager::MenuManager(ServiceProvider* i_sp, GameControls* i_gc)
	: m_sp(i_sp)
	, m_gc(i_gc)
	, m_currentMenu(0)	
{
	assert(i_sp && i_gc);

	m_startingMenu			= new StartingMenu(this);
	m_teamSelectionMenu		= new TeamSelectionMenu(this);
	m_mainMenu				= new MainMenu(this);
	m_teamsManagementMenu	= new TeamsManagementMenu(this);
	m_classificationMenu	= new ClassificationMenu(this);
	m_turnsMenu				= new TurnsMenu(this);
	m_teamsStatsMenu		= new TeamsStatsMenu(this);
	m_leagueStatsMenu		= new LeagueStatsMenu(this);
	m_leagueMenu   		    = new LeagueMenu(this);
	m_leagueSelectionMenu   = new LeagueSelectionMenu(this);
	m_playTurnsMenu			= new PlayTurnsMenu(this);
	m_loadMenu				= new LoadMenu(this);
	m_saveMenu				= new SaveMenu(this);
	m_endLeagueMenu			= new EndLeagueMenu(this);
	m_gameOverMenu			= new GameOverMenu(this);
	m_playersStatsMenu		= new PlayersStatsMenu(this);
	m_playersStatsShowMenu	= new PlayersStatsShowMenu(this);
	m_playerMenu			= new PlayerMenu(this);
	m_teamMenu				= new TeamMenu(this);
	m_teamMatchesMenu		= new TeamMatchesMenu(this);
	m_matchMenu				= new MatchMenu(this);
	m_searchMenu			= new SearchMenu(this);
	m_userSelectionMenu		= new UserSelectionMenu(this);
	m_offerTeamMenu			= new OfferTeamMenu(this);
	m_offerPlayerMenu		= new OfferPlayerMenu(this);
	m_shortListNotificationMenu = new ShortListNotificationMenu(this);
	m_shortListMenu			= new ShortListMenu(this);

	m_leagueHistoryMenu     = new LeagueHistoryMenu(this);
	m_teamHistoryMenu		= new TeamHistoryMenu(this);

	m_confirmPanel			= new ConfirmPanel(this);
	m_notificationPanel		= new NotificationPanel(this);

	SetupEnv();
}

MenuManager::~MenuManager()
{
	delete m_startingMenu;
	delete m_teamSelectionMenu;
	delete m_mainMenu;
	delete m_teamsManagementMenu;
	delete m_classificationMenu;
	delete m_turnsMenu;
	delete m_teamsStatsMenu;
	delete m_leagueStatsMenu;
	delete m_leagueMenu;
	delete m_leagueSelectionMenu;
	delete m_playTurnsMenu;
	delete m_loadMenu;
	delete m_saveMenu;
	delete m_endLeagueMenu;
	delete m_gameOverMenu;
	delete m_playersStatsMenu;
	delete m_playersStatsShowMenu;
	delete m_playerMenu;
	delete m_teamMenu;
	delete m_teamMatchesMenu;
	delete m_matchMenu;
	delete m_searchMenu;
	delete m_userSelectionMenu;
	delete m_offerTeamMenu;
	delete m_offerPlayerMenu;
	delete m_shortListNotificationMenu;
	delete m_shortListMenu;

	delete m_leagueHistoryMenu;
	delete m_teamHistoryMenu;

	delete m_confirmPanel;
	delete m_notificationPanel;
}

void MenuManager::PushMenu(Menu* i_menu)
{
		m_menuStack.push_back(m_currentMenu);
		SetMenu(i_menu);
}

void MenuManager::PopMenu()
{
	if (m_menuStack.empty())
	{
		if(m_currentMenu)
			m_currentMenu->OnExit();
		m_gc->Quit();
	}
	else
	{
		SetMenu(m_menuStack.back());
		m_menuStack.pop_back();
	}
}

void MenuManager::SetMenu(Menu *i_menu)
{
	if(m_currentMenu)
		m_currentMenu->OnExit();
	m_currentMenu = i_menu;
	m_currentMenu->OnEnter();
}

void MenuManager::Run()
{
	assert(m_currentMenu != 0);

	bool goodInput = false;

	while(!goodInput)
	{
		Print::ClearScreen();
		Print::ResetInput();
		
		m_currentMenu->Draw();

		STL::string input;
		STD::cin >> input;

		goodInput = m_currentMenu->Input(input);

		if (!goodInput) 
			STD::cin.clear();
	}
}



#ifdef MS_WINDOWS
// windows specific stuff...
#include <Windows.h>
void MenuManager::SetupEnv()
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD sizes = {Consts::SCREEN_WIDTH, 999};
	SetConsoleScreenBufferSize(handle, sizes);
	SMALL_RECT srect = {0, 0, Consts::SCREEN_WIDTH-1, 79};
	SetConsoleWindowInfo(handle, TRUE, &srect);
}
#else
	#error define a valid SetupEnv for your platform
#endif

